package org.example.contestb.config;

import com.alibaba.fastjson.JSONObject;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Component
@ServerEndpoint("/websocket/{sessionId}")
public class WebSocketServer {

    // 记录当前连接数
    private static final AtomicInteger onlineCount = new AtomicInteger(0);
    
    // 使用ConcurrentHashMap来存储会话信息，确保线程安全
    private static final Map<String, Session> sessions = new ConcurrentHashMap<>();
    
    // 用于调试，记录WebSocketServer实例创建的次数
    private static final AtomicInteger instanceCounter = new AtomicInteger(0);
    
    /**
     * 构造函数，用于验证WebSocketServer是否被正确创建
     */
    public WebSocketServer() {
        int count = instanceCounter.incrementAndGet();
        log.info("=== WebSocketServer实例已创建，当前实例数: {} ===", count);
    }

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("sessionId") String sessionId) {
        // 将会话保存到会话池中
        sessions.put(sessionId, session);
        int count = onlineCount.incrementAndGet();
        log.info("=== WebSocket连接已建立 === ID: {}，当前连接数: {}", sessionId, count);
        
        // 打印所有HTTP请求头，帮助调试
        try {
            Map<String, String> pathParams = session.getPathParameters();
            log.info("=== 路径参数: {} ===", pathParams);
            
            // 发送一条连接成功的消息给客户端
            session.getBasicRemote().sendText("连接已建立成功，sessionId: " + sessionId);
            log.info("=== 初始连接消息已发送 ===");
        } catch (Exception e) {
            log.error("=== 发送连接成功消息异常 ===", e);
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session, @PathParam("sessionId") String sessionId) {
        // 从会话池中移除会话
        sessions.remove(sessionId);
        int count = onlineCount.decrementAndGet();
        log.info("=== WebSocket连接已关闭 === ID: {}，当前连接数: {}", sessionId, count);
    }

    /**
     * 收到客户端消息后调用的方法
     */
    @OnMessage
    public void onMessage(String message, Session session, @PathParam("sessionId") String sessionId) {
        log.info("=== 收到客户端消息 === 客户端: {}, 消息: {}", sessionId, message);
        try {
            // 回复一条消息给客户端
            session.getBasicRemote().sendText("服务器已收到: " + message);
        } catch (Exception e) {
            log.error("=== 处理消息失败 ===", e);
        }
    }

    /**
     * 发生错误时调用的方法
     */
    @OnError
    public void onError(Session session, Throwable error, @PathParam("sessionId") String sessionId) {
        log.error("=== WebSocket发生错误 === sessionId: {}", sessionId, error);
        sessions.remove(sessionId);
        onlineCount.decrementAndGet();
    }

    /**
     * 发送消息给指定客户端
     */
    public static void sendMessage(String sessionId, String message) {
        try {
            Session session = sessions.get(sessionId);
            log.info("=== 尝试发送消息 === 客户端: {}, session存在: {}", sessionId, session != null);
            
            if (session != null && session.isOpen()) {
                synchronized (session) {
                    session.getBasicRemote().sendText(message);
                }
                log.info("=== 消息发送成功 === 客户端: {}, 消息: {}", sessionId, message);
            } else {
                log.warn("=== 无法发送消息 === 客户端: {} 不存在或已关闭", sessionId);
            }
        } catch (IOException e) {
            log.error("=== 发送消息异常 ===", e);
        }
    }

    /**
     * 获取当前连接数
     */
    public static int getOnlineCount() {
        return onlineCount.get();
    }
    
    /**
     * 获取所有会话
     */
    public static Map<String, Session> getSessions() {
        return sessions;
    }
    
    /**
     * 判断指定会话ID是否连接
     */
    public static boolean isConnected(String sessionId) {
        Session session = sessions.get(sessionId);
        return session != null && session.isOpen();
    }
}
